﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IFServerDLL.Broker;
using IFServerDLL.Model;
using System.Runtime.Serialization;
using HCY.CTP.DBShangZheng;
using IFServerDLL;
using IFServerDLL.DB;

namespace IFDemoServer
{

    public class UserInDemoService
    {
        UserOrderTrade _userTrade;
        public UserOrderTrade UserOrderTrade { get { return _userTrade; } }
        public UserInDemoService(BrokerUserBase user)
        {
            _userTrade = new IFServerDLL.Broker.UserOrderTrade(user);
            _RspClient = new RspClient(user.UserID);
        }

        private RspClient _RspClient;
        public RspClient RspClient { get { return _RspClient; } }

        Dictionary<string, MyDBData> _dictMyif = new Dictionary<string, MyDBData>();
        public void AddMarketData(MyDBData data)
        {
            lock (_userTrade)
            {


                while (true)
                {
                    var cedan = UserOrderTrade.OrderHistory.Where(p => p.OrderStatusType == EnumOrderStatusType.撤单 && p.Instrument == data.Instrument).FirstOrDefault();
                    if (cedan != null)
                    {
                        cedan.UpdateState(EnumOrderStatusType.已撤单);

                        RspClient.RspOrder(cedan);
                        UserOrderTrade.Account.Update(_userTrade);
                    }
                    else
                    {
                        break;
                    }
                }
                //触发所有order
                var list = UserOrderTrade.OrderHistory.Where(p => p.IsOnhand() && p.Instrument == data.Instrument).ToList();
                int difTradeVolume = 0;
                if (_dictMyif.ContainsKey(data.Instrument) == false)
                {
                    _dictMyif.Add(data.Instrument, data);
                }
                else
                {
                    difTradeVolume = data.TradeVolume - _dictMyif[data.Instrument].TradeVolume;
                    _dictMyif[data.Instrument] = data;
                }
                list.ForEach(x =>
                {

                    int tradeVolume = 0;

                    if (x.BuyOrSell == MyEnumDirection.Buy)
                    {
                        if (data.NewPrice < x.Price)
                        {
                            tradeVolume = x.NoTradeVolume;
                        }
                        else if (data.NewPrice == x.Price)
                        {
                            if (x.OpenOrClose == MyEnumOpenClose.Open)
                            {
                                tradeVolume = Math.Min(Math.Abs(difTradeVolume) / 3, x.NoTradeVolume);
                            }
                            else
                            {
                                tradeVolume = -Math.Min(Math.Abs(difTradeVolume) / 3, Math.Abs(x.NoTradeVolume));
                            }
                        }
                    }
                    else
                    {
                        if (data.NewPrice > x.Price)
                        {
                            tradeVolume = x.NoTradeVolume;
                        }
                        else if (data.NewPrice == x.Price)
                        {
                            if (x.OpenOrClose == MyEnumOpenClose.Open)
                            {
                                tradeVolume = Math.Min(Math.Abs(difTradeVolume) / 3, x.NoTradeVolume);
                            }
                            else
                            {
                                tradeVolume = -Math.Min(Math.Abs(difTradeVolume) / 3, Math.Abs(x.NoTradeVolume));
                            }
                        }
                    }
                    if (x.OpenOrClose == MyEnumOpenClose.Open)
                    {
                        if (x.TradeVolume + tradeVolume > x.OrdVolume)
                        {
                            tradeVolume = 0;
                        }
                    }
                    else
                    {
                        if (x.TradeVolume + tradeVolume < x.OrdVolume)
                        {
                            tradeVolume = 0;
                        }
                    }

                    if (tradeVolume != 0)
                    {
                        x.UpdateTrade(tradeVolume, data.MarketTime);
                        TradeBase trade = new TradeBase(x, tradeVolume);
                        string msg = UserOrderTrade.AddTrade(trade);
                        if (msg != string.Empty)
                        {
                            RspClient.RspMsg(new MessageBase(msg));

                        }
                        else
                        {
                            RspClient.RspTrade(trade);
                            UserOrderTrade.Account.Update(_userTrade);
                        }
                    }
                    else
                    {
                        //if (x.TradeVolume > 0)
                        //{
                        //    x.UpdateState(EnumOrderStatusType.部分成交还在队列中);
                        //}
                        //else
                        //{
                        //    x.UpdateState(EnumOrderStatusType.未成交还在队列中);
                        //}
                        //RspClient.RspOrder(x);
                    }


                });
            }

        }

        public void OrderInsert(UserOrdBase ord)
        {
            lock (_userTrade)
            {
                if (ord.OpenOrClose == MyEnumOpenClose.Open)
                {
                    OrderBase order = new OrderBase(ord, _dictMyif[ord.Instrument].MarketTime);
                    decimal frozeCash = GlobalStatic.GetCash(order.Instrument, order.OrdVolume, order.Price);
                    decimal frozeCommiss = GlobalStatic.GetCommiss(order.Instrument, order.OrdVolume, order.Price);
                    UserOrderTrade.Account.Update(UserOrderTrade);
                    if (UserOrderTrade.Account.Available - frozeCash - frozeCommiss > 0)
                    {
                        order.UpdateState(EnumOrderStatusType.已触发);
                        RspClient.RspOrder(order);
                        UserOrderTrade.OrderHistory.Add(order);
                        UserOrderTrade.Account.Update(UserOrderTrade);



                    }
                    else
                    {
                        order.StateMsg = "not enough available.";
                        RspClient.RspMsg(new MessageBase("not enough available."));
                    }



                }
                else
                {
                    OrderBase c = new OrderBase(ord, _dictMyif[ord.Instrument].MarketTime);
                    var trade = UserOrderTrade.ListTradeOnhand.Where(p => p.Instrument == ord.Instrument && p.BuyOrSell != ord.BuyOrSell).FirstOrDefault();
                    if (trade == null)
                    {
                        c.StateMsg = "not enough close volume.";
                        RspClient.RspMsg(new MessageBase("not enough close volume."));
                    }
                    else
                    {
                        if (trade.SumALLVolume < c.OrdVolume)
                        {
                            c.StateMsg = "not enough close volume.";
                            RspClient.RspMsg(new MessageBase("not enough close volume."));
                            return;
                        }
                        else
                        {
                            c.UpdateState(EnumOrderStatusType.已触发);
                            RspClient.RspOrder(c);
                            UserOrderTrade.OrderHistory.Add(c);

                        }
                    }

                }
            }
        }

        public void OrderCancel(Guid orderID, Guid calcID)
        {
            lock (_userTrade)
            {
                var order = UserOrderTrade.OrderHistory.Where(p => p.OrdID == orderID).FirstOrDefault();
                if (order != null)
                {
                    order.CalcCancelID = calcID;
                    order.OrderStatusType = EnumOrderStatusType.撤单;
                    UserOrderTrade.Account.Update(UserOrderTrade);
                    RspClient.RspOrder(order);
                }
                else
                {
                    RspClient.RspMsg(new MessageBase("no exist orderid " + orderID));
                }
            }
        }

    }
}
